package edu.gatech.gro;

import java.util.regex.Pattern;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import edu.gatech.gro.http.IResponseAdapter;
import edu.gatech.gro.model.ObjectResponse;
import edu.gatech.gro.model.User;
import edu.gatech.gro.utils.Utils;

public class UserEditActivity extends Activity {

	private static final String TAG = "USER_EDIT_ACTIVITY";

	private static final int ERROR_PASSWORD_DIFFERENT = 0;
	private static final int ERROR_USERNAME_RULE = 1;
	private static final int ERROR_PASSWORD_RULE = 2;
	// private static final int ERROR_ONLINE = 3;

	private static GroceryListManagerApplication app;

	private ProgressDialog mProgressCreation;
	private AlertDialog mAlertDialog;

	private Button mCreateUserButton;
	private EditText mUsername;
	private EditText mEmail;
	private EditText mPassword1;
	private EditText mPassword2;

	private User mCurrentUser;

	@Override
	public void onCreate(Bundle bundle) {
		super.onCreate(bundle);

		app = (GroceryListManagerApplication) getApplicationContext();

		setContentView(R.layout.user_adder);

		mAlertDialog = new AlertDialog.Builder(UserEditActivity.this).create();
		mAlertDialog.setButton("OK", new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
			}
		});

		mCreateUserButton = (Button) findViewById(R.id.userAdderCreateUserButton);
		mUsername = (EditText) findViewById(R.id.userAdderUsernameText);
		mEmail = (EditText) findViewById(R.id.userAdderEmailText);
		mPassword1 = (EditText) findViewById(R.id.userAdderPassword1Text);
		mPassword2 = (EditText) findViewById(R.id.userAdderPassword2Text);

		mCurrentUser = null;
		Bundle extra = getIntent().getExtras();
		if (extra.getBoolean("hasUser")) {
			Log.d(TAG, "Has user");
			mCurrentUser = new User();
			mCurrentUser.setId(extra.getInt("id"));
			mCurrentUser.setUsername(extra.getString("username"));
			mCurrentUser.setEmail(extra.getString("email"));
			mUsername.setText(mCurrentUser.getUsername());
			mEmail.setText(mCurrentUser.getEmail());
			mCreateUserButton.setText(R.string.userAdderUpdateUserButtonLabel);
			mPassword1.setVisibility(EditText.GONE);
			mPassword2.setVisibility(EditText.GONE);
			((TextView) findViewById(R.id.userAdderPassword1)).setVisibility(TextView.GONE);
			((TextView) findViewById(R.id.userAdderPassword2)).setVisibility(TextView.GONE);
		}

		mCreateUserButton.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				Log.d(TAG, "Create user button clicked!");
				if (mCurrentUser == null) {
					saveUser();
				} else {
					updateUser();
				}
			}
		});
	}

	private boolean saveUser() {
		if (mProgressCreation != null && mProgressCreation.isShowing()) {
			return false;
		}

		String username = mUsername.getText().toString();
		String email = mEmail.getText().toString();
		String password1 = mPassword1.getText().toString();
		String password2 = mPassword2.getText().toString();

		if (!isUsername(username)) {
			return displayError(ERROR_USERNAME_RULE);
		}
		if (!isPassword(password1)) {
			return displayError(ERROR_PASSWORD_RULE);
		}
		if (!password1.equals(password2)) {
			return displayError(ERROR_PASSWORD_DIFFERENT);
		}

		mCurrentUser = new User();
		mCurrentUser.setId(0);
		mCurrentUser.setUsername(username);
		mCurrentUser.setEmail(email);
		mCurrentUser.setPassword(Utils.hash(password1));

		mProgressCreation = ProgressDialog.show(UserEditActivity.this, "", this.getString(R.string.progressUserCreation), true, false);
		app.saveUser(mCurrentUser, mUserRegisteredListener);
		return true;
	}

	private boolean updateUser() {
		if (mProgressCreation != null && mProgressCreation.isShowing()) {
			return false;
		}

		String username = mUsername.getText().toString();
		String email = mEmail.getText().toString();

		if (!isUsername(username)) {
			return displayError(ERROR_USERNAME_RULE);
		}

		mCurrentUser.setUsername(username);
		mCurrentUser.setEmail(email);

		mProgressCreation = ProgressDialog.show(UserEditActivity.this, "", this.getString(R.string.progressUserUpdate), true, false);
		app.updateUser(mCurrentUser, mUserUpdatedListener);
		return true;
	}

	private boolean displayError(int errorCode) {
		switch (errorCode) {
			case ERROR_PASSWORD_DIFFERENT:
				displayError(R.string.errorPasswordDifferentTitle, R.string.errorPasswordDifferentMessage);
				break;
			case ERROR_USERNAME_RULE:
				displayError(R.string.errorUsernameRuleTitle, R.string.errorUsernameRuleMessage);
				break;
			case ERROR_PASSWORD_RULE:
				displayError(R.string.errorPasswordRuleTitle, R.string.errorPasswordRuleMessage);
				break;
		}
		return false;
	}

	private boolean isUsername(String username) {
		String pattern = "^([a-zâêîôûŷäëïöüÿéèàçùA-ZÂÊÎÔÛŶÄËÏÖÜŸÉÈÀÇÙ0-9 '\\-]+)$";
		return Pattern.compile(pattern).matcher(username).find();
	}

	private boolean isPassword(String password) {
		String regMin = "a-zâêîôûŷäëïöüÿéèàçùæœ";
		String regMaj = "A-ZÂÊÎÔÛŶÄËÏÖÜŸÉÈÀÇÙÆŒ";
		String regNum = "0-9";
		String regSym = "²&~\"'\\{\\(\\[\\-\\|`_\\^@\\)\\]=\\}\\*\\$£%<>,;:!§\\/\\.\\?";
		String patternFull = "^([" + regMin + regMaj + regNum + regSym + "]{6,})$";
		String patternLetter = "([" + regMin + "|" + regMaj + "]+)";
		String patternNum = "([" + regNum + "]+)";
		String patternSym = "([" + regSym + "]+)";

		password = password.trim();
		if (password.length() < 6) {
			return false;
		}
		boolean b1 = Pattern.compile(patternFull).matcher(password).find();
		boolean b2 = Pattern.compile(patternLetter).matcher(password).find();
		boolean b3 = Pattern.compile(patternNum).matcher(password).find();
		boolean b4 = Pattern.compile(patternSym).matcher(password).find();
		return b1 && b2 && b3 && b4;
	}

	/**
	 * Helper function to dismiss a progress dialog
	 * 
	 * @param theProgress
	 *          the progress dialog to dismiss
	 */
	private void dismissProgress(ProgressDialog theProgress) {
		if (theProgress != null && theProgress.isShowing()) {
			theProgress.dismiss();
		}
	}

	private final IResponseAdapter mUserRegisteredListener = new IResponseAdapter() {

		@Override
		public void onResponse(ObjectResponse response) {
			dismissProgress(mProgressCreation);
			if (response.isSuccessful()) {
				finish();
			} else {
				displayError(R.string.failCreateUserTitle, response.getErrorsAsString());
			}
		}
	};

	private final IResponseAdapter mUserUpdatedListener = new IResponseAdapter() {

		@Override
		public void onResponse(ObjectResponse response) {
			dismissProgress(mProgressCreation);
			if (response.isSuccessful()) {
				Intent b = new Intent();
				b.putExtra("id", mCurrentUser.getId());
				b.putExtra("username", mCurrentUser.getUsername());
				b.putExtra("email", mCurrentUser.getEmail());
				setResult(RESULT_OK, b);
				finish();
			} else {
				displayError(R.string.failUpdateUserTitle, response.getErrorsAsString());
			}
		}
	};

	private void displayError(final int titleId, final int messageId) {
		mAlertDialog.setTitle(titleId);
		mAlertDialog.setMessage(this.getString(messageId));
		mAlertDialog.show();
	}

	private void displayError(final int titleId, final String message) {
		mAlertDialog.setTitle(titleId);
		mAlertDialog.setMessage(message);
		mAlertDialog.show();
	}
}
